<?php
/**
 * Created by PhpStorm.
 * User: sunzexin
 * Date: 2018/1/21
 * Time: 11:10
 */

namespace App\Http\Logics\MiniProgram;

use App\Address;
use App\Cart;
use App\Goods;
use App\GoodsMappingOrder;
use App\Http\Logics\BaseLogic;
use App\Order;
use App\Users;
use Carbon\Carbon;
use Illuminate\Support\Facades\DB;

class OrderLogic extends BaseLogic
{
    public static function createOrder($data)
    {
        $order = new Order();
        DB::transaction(function () use ($data, $order) {
            $cart_id_arr = explode(',', $data['cart_id_str']);
            $cart = Cart::with(['goods', 'goods.product'])->whereIn('id', $cart_id_arr)->get();
            if (empty($cart)) {
                return self::response(self::CONTENT_IS_EMPTY);
            }
            if (!$order->save()) {
                return self::response(self::OBJECT_SAVE_FAIL);
            }

            // 订单总价
            $total_money = 0;
            // 总运费
            $total_carriage = 0;

            foreach ($cart as $item) {
                $total_money = $total_money + $item->goods->price * $item->num;
                $total_money = $total_money + $item->goods->product->carriage;
                $total_carriage = $total_carriage + $item->goods->product->carriage;
                $goods_mapping_order = new GoodsMappingOrder();
                $goods_mapping_order->goods_id = $item->goods->id;
                $goods_mapping_order->order_id = $order->id;
                $goods_mapping_order->price = $item->goods->price;
                $goods_mapping_order->num = $item->num;
                $goods_mapping_order->icon = $item->goods->icon;
                $goods_mapping_order->name = $item->goods->product->name.$item->goods->standard;
                if (!$goods_mapping_order->save()) {
                    return self::response(self::OBJECT_SAVE_FAIL);
                }
            }

            $response = self::getUserIdByLoginSession($data['loginSession']);
            if ($response->code) {
                return self::response($response->code);
            }
            $user_id = $response->data;
            $order->no = strtoupper('NO'.date('Y').date('m').date('d').date('h').date('i').randomStr(6));
            $order->name = '好物订单';
            $order->user_id = $user_id;
            $order->total_money = $total_money;
            $order->total_carriage = $total_carriage;
            $order->cart_id_str = $data['cart_id_str'];
            $order->expired_at = Carbon::parse('+15 minutes');
            if (!$order->save()) {
                return self::response(self::OBJECT_SAVE_FAIL);
            }
        });
        return self::response(self::SUCCESS, $order->id);
    }

    public static function getOrderDetail($data)
    {

        $response = self::getUserIdByLoginSession($data['loginSession']);
        if ($response->code) {
            return self::response($response->code);
        }
        $user_id = $response->data;
        $order = Order::with(['user', 'goods', 'goods.product'])->where('user_id', $user_id)->find($data['order_id']);
        if (empty($order)){
            return self::response(self::CONTENT_IS_EMPTY);
        }
        $order->goods->map(function ($goods) {
            $goods->pivot->price = $goods->pivot->price / 100;
            return $goods;
        });
        $order->append(['total_goods_money']);
        if ($order->status === Order::NOT_PAY){
            $order->append(['rest_time']);
        }
        return self::response(self::SUCCESS, $order);
    }

    public static function pay($data)
    {
        $response = self::getUserIdByLoginSession($data['loginSession']);
        if ($response->code) {
            return self::response($response->code);
        }
        $user_id = $response->data;
        $order = Order::where(function($query) use ($user_id, $data){
            $query->where('user_id', $user_id);
            $query->where('id', $data['order_id']);
        })->first();
        if (empty($order)){
            return self::response(self::CONTENT_IS_EMPTY);
        }

        // 减商品库存
        $cart = Cart::with(['goods'])->whereIn('id', explode(',', $order->cart_id_str))->get();
        if (empty($cart)){
            return self::response(self::CONTENT_IS_EMPTY);
        }
        foreach ($cart as $item){
            $goods = Goods::find($item->goods->id);
            if (empty($goods)){
                return self::response(self::CONTENT_IS_EMPTY);
            }
            $goods->num = $goods->num - $item->num;
            if (!$goods->save()){
                return self::response(self::OBJECT_SAVE_FAIL);
            }
        }

        // 避免重复支付
        if ($order->status == Order::HAS_PAY){
            return self::response(self::PAY_AGAIN);
        }

        if (isset($data['address_id']) && $data['address_id']){
            $address = Address::find($data['address_id']);
            if (empty($address)){
                return self::response(self::CONTENT_IS_EMPTY);
            }

            $order->username = $address->username;
            $order->postalcode = $address->postalcode;
            $order->address = $address->province.$address->city.$address->district.$address->detail_info;
            $order->mobile = $address->mobile;
            $order->status = Order::NOT_PAY;
            if (!$order->save()){
                return self::response(self::OBJECT_SAVE_FAIL);
            }
        }

        // 删除购物车中已结算的商品
        Cart::whereIn('id', explode(',', $order->cart_id_str))->delete();
        // 删除该用户所有状态为0的订单
        Order::where('user_id', $user_id)->where('status', 0)->forceDelete();

        $open_id = Users::select('wx_app_openid')->find($user_id)->wx_app_openid;
        // 微信支付
        $app = app('wechat.payment');
        $out_trade_no = $order->no;
        $total_fee = $order->total_money;
        $body = $order->name;
        $result = $app->order->unify([
            'body' => $body,
            'out_trade_no' => $out_trade_no,
            'total_fee' => $total_fee*100,
            'notify_url' => 'http://web3.yiicca.com/api/order/callback', // 支付结果通知网址，如果不设置则会使用配置里的默认地址
            'trade_type' => 'JSAPI',
            'openid' => $open_id,
        ]);
        errorLog($result);
        $parameters = array(
            'appId' =>'wxb980d6dc4b2c0314',
            'timeStamp' =>''.time().'',
            'nonceStr' => randomStr(10),
            'package' =>'prepay_id='.$result['prepay_id'],
            'signType' =>'MD5'
        );
        // 签名
        $parameters['paySign']=self::getSign($parameters);
        return self::response(self::SUCCESS, $parameters);
    }

    /**
     * 创建随机字符串
     * @param int $length
     * @return string
     */
    public static function createNoncestr($length = 32 ){
        $chars = "abcdefghijklmnopqrstuvwxyz0123456789";
        $str ="";
        for ( $i = 0; $i < $length; $i++ ) {
            $str.= substr($chars, mt_rand(0, strlen($chars)-1), 1);
        }
        return $str;
    }

    /**
     * 生成签名
     * @param $Obj
     * @return string
     */
    public static function getSign($parameters){
        //签名步骤一：按字典序排序参数
        $string = self::formatBizQueryParaMap($parameters, false);
        //签名步骤二：在string后加入KEY
        $string = $string.'&key=Y2017Ccai4sfsaljLAsiANHL9D076HJE';
        //签名步骤三：MD5加密
        $string = md5($string);
        //签名步骤四：所有字符转为大写
        $result = strtoupper($string);
        return $result;
    }

    /**
     * @param $para
     * @param $urlencode
     * @return bool|string
     */
    public static function formatBizQueryParaMap($para, $urlencode){
        $buff = "";
        ksort($para);
        foreach ($para as $k => $v){
            if($urlencode)
            {
                $v = urlencode($v);
            }
            $buff .= $k . "=" . $v . "&";
        }
        if (strlen($buff) > 0){
            $req = substr($buff, 0, strlen($buff)-1);
        }
        return $req;
    }

    public static function paySuccess($data)
    {
        $order = Order::find($data['order_id']);
        if (empty($order)){
            return self::response(self::CONTENT_IS_EMPTY);
        }
        $order->status = Order::HAS_PAY;
        // 记录支付时间
        $order->pay_time = time();
        if (!$order->save()){
            return self::response(self::OBJECT_SAVE_FAIL);
        }
        return self::response(self::SUCCESS);
    }

    public static function callback($post_data)
    {
        $order = Order::where(function($query) use ($post_data){
            $query->where('no', $post_data['out_trade_no']);
        })->first();

        if($post_data['return_code']=='SUCCESS'){
            /*
            * 首先判断，订单是否已经更新为ok，因为微信会总共发送8次回调确认
            * 其次，订单已经为ok的，直接返回SUCCESS
            * 最后，订单没有为ok的，更新状态为ok，返回SUCCESS
            */
            if($order->status != Order::HAS_PAY){
                Order::where(function($query) use ($post_data){
                    $query->where('no', $post_data['out_trade_no']);
                })->update(['status' => Order::HAS_PAY, 'pay_time' => time()]);
            }
            $return['return_code'] = 'SUCCESS';
            $return['return_msg'] = 'OK';
            $xml_post = '<xml>
                <return_code>'.$return['return_code'].'</return_code>
                <return_msg>'.$return['return_msg'].'</return_msg>
                </xml>';
            echo $xml_post;
            exit;
        }else{
            return self::response(self::PAY_FAILD);
        }
    }

    public static function getOrderList($data)
    {
        $response = self::getUserIdByLoginSession($data['loginSession']);
        if ($response->code) {
            return self::response($response->code);
        }
        $user_id = $response->data;

        // 把失效的未支付订单删除掉，并恢复对于商品的库存
        $order = Order::where('expired_at', '<', time())->where('status', Order::NOT_PAY)->get();
        if (empty($order)){
            return self::response(self::CONTENT_IS_EMPTY);
        }
        foreach ($order as $value){
            // 恢复商品库存
            $cart = Cart::with(['goods'])->whereIn('id', explode(',', $value->cart_id_str))->withTrashed()->get();
            if (empty($cart)){
                return self::response(self::CONTENT_IS_EMPTY);
            }
            foreach ($cart as $item){
                $goods = Goods::find($item->goods->id);
                if (empty($goods)){
                    return self::response(self::CONTENT_IS_EMPTY);
                }
                $goods->num = $goods->num + $item->num;
                if (!$goods->save()){
                    return self::response(self::OBJECT_SAVE_FAIL);
                }
            }

            // 商品库存恢复后将该订单删除
            if (!$value->delete()){
                return self::response(self::OBJECT_DELETE_FAILD);
            }
        }

        $query = Order::with(['goods', 'goods.product'])->where(function($query) use ($data, $user_id){
            $query->where('user_id', $user_id);
            if (isset($data['status']) && $data['status']){
                $query->where('status', $data['status']);
            }
        })->orderBy('id', 'desc');
        $order = $data['limit'] ? $query->paginate($data['limit']) : $query->get();
        if (empty($order)){
            return self::response(self::CONTENT_IS_EMPTY);
        }
        return self::response(self::SUCCESS, $order);
    }

    public static function wlcx($data)
    {
        $courier_number = Order::select('courier_number')->find($data['order_id'])->courier_number;
        $query_data = [
            'number' => $courier_number,
            'type' => 'auto'
        ];

        // 获取快递物流信息
        $appcode = "b38de016e7c24ba8b9e3d478b18cbfa4";
        $headers = [
            "Authorization:APPCODE " . $appcode
        ];
        $url = "http://jisukdcx.market.alicloudapi.com/express/query?".http_build_query($query_data);
        $result = self::httpGet($url, $headers);
        if (objectToArray(json_decode($result->data))['status']){
            return self::response(self::WLXX_FAILD);
        }
        $result_data_arr = objectToArray(json_decode($result->data));

        // 请求快递公司数据
        $url2 = 'http://jisukdcx.market.alicloudapi.com/express/type';
        $result2 = self::httpGet($url2, $headers);
        $result2_data_arr = objectToArray(json_decode($result2->data));

        // 给物流信息加上快递名称
        foreach ($result2_data_arr['result'] as $item){
            if ($item['type'] == strtoupper($result_data_arr['result']['type'])){
                $result_data_arr['result']['name'] = $item['name'];
                break;
            }
            continue;
        }
        return self::response(self::SUCCESS, $result_data_arr['result']);
    }

    public static function confirmReceive($data)
    {
        $order = Order::find($data['order_id']);
        if (empty($order)){
            return self::response(self::SET_CAFE_PASS_AGAIN);
        }
        $order->status = Order::HAS_COMPLETE;
        if (!$order->save()){
            return self::response(self::OBJECT_SAVE_FAIL);
        }
        return self::response(self::SUCCESS);
    }

    /**
     * 直接购买
     * @param $data
     * @return mixed
     */
    public static function directBuy($data)
    {
        $order = new Order();
        DB::transaction(function () use ($data, $order) {
            if (!$order->save()) {
                return self::response(self::OBJECT_SAVE_FAIL);
            }

            // 订单总价
            $total_money = 0;
            // 总运费
            $total_carriage = 0;

            $goods = Goods::with(['product'])->find($data['goods_id']);
            if (empty($goods)){
                return self::response(self::CONTENT_IS_EMPTY);
            }

            $total_money = $total_money + $goods->price * $data['num'];
            $total_money = $total_money + $goods->product->carriage;

            $total_carriage = $total_carriage + $goods->product->carriage;
            $goods_mapping_order = new GoodsMappingOrder();
            $goods_mapping_order->goods_id = $goods->id;
            $goods_mapping_order->order_id = $order->id;
            $goods_mapping_order->price = $goods->price;
            $goods_mapping_order->num = $data['num'];
            $goods_mapping_order->icon = $goods->icon;
            $goods_mapping_order->name = $goods->product->name.$goods->standard;
            if (!$goods_mapping_order->save()) {
                return self::response(self::OBJECT_SAVE_FAIL);
            }

            $response = self::getUserIdByLoginSession($data['loginSession']);
            if ($response->code) {
                return self::response($response->code);
            }
            $user_id = $response->data;

            // 伪造个购物车
            $cart = new Cart();
            $cart->user_id = $user_id;
            $cart->num = $data['num'];
            $cart->goods_id = $data['goods_id'];
            if (!$cart->save()){
                return self::response(self::OBJECT_SAVE_FAIL);
            }

            $order->no = strtoupper('NO'.date('Y').date('m').date('d').date('h').date('i').randomStr(6));
            $order->name = '好物订单';
            $order->user_id = $user_id;
            $order->cart_id_str = $cart->id;
            $order->total_money = $total_money;
            $order->total_carriage = $total_carriage;
            $order->expired_at = Carbon::parse('+15 minutes');
            if (!$order->save()) {
                return self::response(self::OBJECT_SAVE_FAIL);
            }
        });
        return self::response(self::SUCCESS, $order->id);
    }

    /**
     * 取消订单
     * @param $data
     * @return mixed
     * @throws \Exception
     */
    public static function cancelOrder($data)
    {
        $response = self::getUserIdByLoginSession($data['loginSession']);
        if ($response->code) {
            return self::response($response->code);
        }
        $user_id = $response->data;
        $order = Order::where(function ($query) use ($user_id, $data){
            $query->where('user_id', $user_id);
        })->find($data['order_id']);
        if (empty($order)){
            return self::response(self::CONTENT_IS_EMPTY);
        }

        // 判断该订单是否退款
        if ($order->status === Order::NOT_PAY){
            $order->status = Order::CANCEL_ORDER;
        }else{
            $order->status = Order::WAIT_REFUND;
        }

        // 恢复商品库存
        $cart = Cart::with(['goods'])->whereIn('id', explode(',', $order->cart_id_str))->withTrashed()->get();
        if (empty($cart)){
            return self::response(self::CONTENT_IS_EMPTY);
        }
        foreach ($cart as $item){
            $goods = Goods::find($item->goods->id);
            if (empty($goods)){
                return self::response(self::CONTENT_IS_EMPTY);
            }
            $goods->num = $goods->num + $item->num;
            if (!$goods->save()){
                return self::response(self::OBJECT_SAVE_FAIL);
            }
        }
        if (!$order->save()){
            return self::response(self::OBJECT_DELETE_FAILD);
        }
        return self::response(self::SUCCESS);
    }
}